/**
 * @format
 * @Author: TC
 * @Date: 2023-02-17 21:26:21
 * @Last Modified by: TC
 * @Last Modified time: 2025-05-05 01:51:19
 */

import { director, macro, Scheduler } from "cc";
import { app } from "../App";
import { ITimerInstance } from "../Module/Timer/TimerInterface";
import { TimerUnit } from "../Module/Timer/TimerUnit";

/**
 * 定时器管理
 */
export class TimerManager {
    public id: string;
    public uuid: string;
    private _mapTimer: Map<number, TimerUnit> = null;
    private _timerId: number = 0;
    private _scale: number = 1;

    constructor() {
        this._mapTimer = new Map();
    }

    /**
     * 启动全局定时器
     */
    public start(): void {
        Scheduler.enableForTarget(this);
        director.getScheduler().schedule(this.onUpdate, this, 0, macro.REPEAT_FOREVER, 0, true);
        director.getScheduler().resumeTarget(this);
    }

    private onUpdate(dt: number): void {
        this._mapTimer.forEach((timer, index) => {
            timer.update(dt * this._scale);
            if (timer.completed) {
                this.unschedule(timer.timerId);
            }
        });
    }

    /**
     * 设置时间缩放
     * @param scale
     */
    public setScale(scale: number): void {
        this._scale = scale;
    }
    /**
     * 开启一个定时器
     * @param callback
     * @param thisObj
     * @param arg
     * @param interval
     * @param repeat
     * @param delay
     * @returns
     */
    public schedule(
        callback: Function,
        thisObj: any,
        arg: any = null,
        interval: number,
        repeat: number,
        delay: number = 0
    ): number {
        const iTimer: ITimerInstance = {
            timerId: this._timerId,
            delayTime: delay,
            executeTimes: repeat,
            interval: interval,
            callback: callback,
            thisObj: thisObj,
            arg: arg,
        };
        const timer = new TimerUnit(iTimer);
        this._mapTimer.set(this._timerId, timer);
        return this._timerId++;
    }

    /**
     * 开启单次定时器
     * @param callback
     * @param thisObj
     * @param arg
     * @param delay
     */
    public scheduleOnce(callback: Function, delay: number, thisObj: any, arg: any = null): number {
        return this.schedule(callback, thisObj, arg, delay, 1, 0);
    }

    /**
     * 删除一个定时器
     * @param id
     */
    public unschedule(id: number): void {
        const timer = this._mapTimer.get(id);
        if (!timer) {
            app.log.error("timer not found - " + id);
            return;
        }
        timer.release();
        this._mapTimer.delete(id);
    }

    /**
     * 暂停一个定时器
     * @param id
     */
    public pause(id: number): void {
        const timer = this._mapTimer.get(id);
        if (!timer) {
            app.log.error("timer not found - " + id);
            return;
        }
        timer.pause();
    }

    /**
     * 恢复一个定时器
     * @param id
     */
    public resume(id: number): void {
        const timer = this._mapTimer.get(id);
        if (!timer) {
            app.log.error("timer not found - " + id);
            return;
        }
        timer.resume();
    }

    public release(): void {
        this._mapTimer.forEach((timer) => {
            timer.release();
        });
        this._mapTimer.clear();
        this._mapTimer = null;
    }
}
